<?php
namespace app\common\lib\RoyCloud\Common;

use app\common\lib\RoyCloud\Common\Exception\RoyException;
use app\common\model\RoymqQueueModel;
use app\common\model\RoymqTopicModel;

abstract class AbstractClient
{
    public function __construct()
    {
    }

    /**
     * 通用方法(外面调用的方法不存在时调用时方法)
     * @author 贺强
     * @time   2022/6/29 17:00
     * @param string $action    调用的方法名
     * @param mixed  $arguments 携带的参数
     * @return mixed 结果
     */
    public function __call($action, $arguments)
    {
        try {
            switch ($action) {
                case 'CreateQueue':
                    $result = $this->addQueue($arguments);
                    break;
                case 'ModifyQueue':
                    $result = $this->modifyQueue($arguments);
                    break;
                case 'CreateTopic':
                    $result = $this->addTopic($arguments);
                    break;
                case 'SendMessage':
                    $result = $this->SendMsg($arguments);
                    break;
                default:
                    throw new RoyException('Action [' . $action . '] not exists');
            }
            return $this->returnResponse($action, $result);
        } catch (RoyException $e) {
            return null;
        }
    }

    // region queue

    /**
     * 创建队列
     * @author roy
     * @time   2022/6/20 16:30
     * @param mixed $arguments 创建队列参数
     * @return array 返回添加的队列信息
     * @throws RoyException
     */
    private function addQueue($arguments)
    {
        if (empty($arguments[0]->QueueName)) {
            throw new RoyException('QueueName is a required parameter.');
        }
        $queue_name = $arguments[0]->QueueName;
        if (mb_strlen($queue_name) > 64 || mb_strlen($queue_name) < 3) {
            throw new RoyException('The length of [QueueName] is 3-64.');
        }
        if (!empty($arguments[0]->Remark) && mb_strlen($arguments[0]->Remark) > 128) {
            throw new RoyException('The length or [Remark] must not exceed 128.');
        }
        $count = RoymqQueueModel::getCount(['queue_name' => $queue_name]);
        if ($count) {
            throw new RoyException('QueueName [' . $queue_name . '] already exists.');
        }
        $id = md5(get_millisecond() . '@queue@' . get_random_str());
        $time = $arguments[0]->Ctime ?? time();
        $param = [
            'Id' => $id,
            'QueueName' => $queue_name,
            'Remark' => $arguments[0]->Remark ?? '',
            'ctime' => $time,
        ];
        queue('app\\common\\job\\QueueJob@add_queue', $param);
        $param['CreateTime'] = date('Y-m-d H:i:s', $time);
        unset($param['ctime']);
        return $param;
    }

    /**
     * 修改队列
     * @author 贺强
     * @time   2022/6/23 13:59
     * @param array $arguments 修改参数
     * @return array
     */
    private function modifyQueue($arguments)
    {
        return $arguments;
    }
    // endregion
    // region topic
    /**
     * 创建主题
     * @author roy
     * @time   2022/6/20 16:32
     * @param mixed $arguments 创建主题参数
     * @return array 返回添加的队列信息
     * @throws RoyException
     */
    private function addTopic($arguments)
    {
        if (empty($arguments[0]->TopicName)) {
            throw new RoyException('TopicName is a required parameter.');
        }
        $topic_name = $arguments[0]->TopicName;
        if (mb_strlen($topic_name) > 64 || mb_strlen($topic_name) < 3) {
            throw new RoyException('The length of [TopicName] is 3-64.');
        }
        if (!empty($arguments[0]->Remark) && mb_strlen($arguments[0]->Remark) > 128) {
            throw new RoyException('The length of the [Remark] must not exceed 128.');
        }
        $count = RoymqTopicModel::getCount(['topic_name' => $topic_name]);
        if ($count) {
            throw new RoyException('TopicName [' . $topic_name . '] already exists.');
        }
        $id = md5(get_millisecond() . '@topic@' . get_random_str());
        $time = $arguments[0]->Ctime ?? time();
        $param = [
            'Id' => $id,
            'TopicName' => $topic_name,
            'Remark' => $arguments[0]->Remark ?? '',
            'ctime' => $time,
        ];
        queue('app\\common\\job\\TopicJob@add_topic', $param);
        $param['CreateTime'] = date('Y-m-d H:i:s', $time);
        unset($param['ctime']);
        return $param;
    }
    // endregion
    // region message
    /**
     * 发送消息
     * @author roy
     * @time   2022/6/20 16:34
     * @param mixed $arguments 发送消息参数
     * @return array 返回队列信息
     * @throws RoyException
     */
    private function SendMsg($arguments)
    {
        if (empty($arguments[0]->MsgBody)) {
            throw new RoyException('MsgBody is a required parameter.');
        } elseif (empty($arguments[0]->QueueName)) {
            throw new RoyException('QueueName is a required parameter.');
        }
        $queue = $arguments[0]->QueueName;
        $count = RoymqQueueModel::getCount(['queue_name' => $queue]);
        if (!$count) {
            throw new RoyException('QueueName [' . $queue . '] is not exists.');
        }
        $topic = $arguments[0]->TopicName ?? '';
        if (!empty($topic)) {
            $count = RoymqTopicModel::getCount(['topic_name' => $topic]);
            if (!$count) {
                throw new RoyException('TopicName [' . $topic . '] is not exists.');
            }
        }
        $id = md5(get_millisecond() . '@message@' . get_random_str());
        $time = $arguments[0]->Ctime ?? time();
        $param = [
            'Id' => $id,
            'MsgBody' => $arguments[0]->MsgBody,
            'QueueName' => $queue,
            'ctime' => $time,
        ];
        if (!empty($topic)) {
            $param['TopicName'] = $topic;
        }
        queue('app\\common\\job\\MessageJob@send_msg', $param);
        $param['CreateTime'] = date('Y-m-d H:i:s', $time);
        unset($param['ctime']);
        return $param;
    }
    // endregion
}
